<template>
    <a-row :gutter="16">
        <a-alert banner message="加载失败，请刷新重试" type="error" v-if="failedLoading"/>
        <a-col :span="20" class="gutter-row">
            <a-list :data-source="articles" :loading="loading" class="gutter-box" item-layout="vertical" size="large" :rowKey="item => item.id">
                <div
                        :style="{ textAlign: 'center', marginTop: '12px', height: '32px', lineHeight: '32px' }"
                        slot="loadMore"
                        v-if="showLoadingMore"
                >
                    <a-spin v-if="loadingMore"/>
                    <a-button @click="onLoadMore" class="loadmore-btn" v-else>
                        阅读更多
                    </a-button>
                </div>
                <a-list-item key="item.title" slot="renderItem" slot-scope="item">
                    <template slot="actions" v-for="{ type, icon, count, theme } in item.actions">
                        <span :key="type" @click="articleAction(articles.indexOf(item), type)">
                          <a-icon :type="icon" style="margin-right: 8px" :theme="theme" two-tone-color="#eb2f96"/>
                          {{ count }}
                        </span>
                    </template>
                    <img
                            alt="logo"
                            slot="extra"
                            :src="item.thumbnail"
                            width="272"
                            v-if="item.thumbnail"
                    />
                    <a-list-item-meta>
                        <router-link :to="'/article/' + item.id" slot="title">{{ item.title }}</router-link>
                        <!--                        <a-avatar :src="item.avatar" slot="avatar"/>-->
                    </a-list-item-meta>
                    <span class="description">{{ item.description }}</span>
                </a-list-item>
            </a-list>
        </a-col>
        <a-col :span="4" class="gutter-row">
            <ListCard :offset-top="affixOffsetTop" class="gutter-box" source="author" title="推荐作者"></ListCard>
        </a-col>
    </a-row>
</template>

<script>
    import {Alert, Button, Col, Icon, List, Row, Spin} from "ant-design-vue";
    import ListCard from "../components/ListCard";
    import axios from "axios";

    export default {
        name: "Home",
        components: {
            AList: List,
            AListItem: List.Item,
            AListItemMeta: List.Item.Meta,
            AIcon: Icon,
            // AAvatar: Avatar,
            ASpin: Spin,
            AButton: Button,
            ARow: Row,
            ACol: Col,
            AAlert: Alert,

            ListCard,
        },
        data() {
            return {
                articles: [],
                loading: true,
                loadingMore: false,
                showLoadingMore: false,
                failedLoading: false,
                page: 1,  // 当前请求文章的页数
                per_page: 10  // 每一页显示多少
            };
        },
        computed: {
            affixOffsetTop: function () {
                return document.getElementById('headerBar').offsetHeight + 25;
            }
        },
        mounted() {
            // 修改面包屑
            this.$emit('changePaths', [{link: '/', name: '首页'}]);

            let vue = this;
            axios.get("/article/").then(function (response) {
                let data = response.data, articles = response.data.data;
                vue.articles = vue.parseActionsData(articles);
                vue.loading = false;
                vue.showLoadingMore = data.has_next;
                vue.page++;  // 加载成功后加页数，否则不加
            }).catch(function (e) {
                console.error(e)
                vue.failedLoading = true;
                vue.loading = false;
            })
        },
        methods: {
            onLoadMore() {
                let vue = this;

                this.loadingMore = true;
                axios.get("/article/", {
                    params: {
                        page: this.page,
                        per_page: this.per_page
                    }
                }).then(function (response) {
                    let data = response.data, articles = response.data.data;
                    vue.articles = vue.articles.concat(vue.parseActionsData(articles));
                    vue.showLoadingMore = data.has_next;
                    vue.loadingMore = false;
                    vue.page++;
                    vue.$nextTick(() => {
                        window.dispatchEvent(new Event('resize'));
                    });
                });
            },
            articleAction: function (itemIndex, type) {
                if (type !== 'like') return;
                let postData = {action: type};
                let actionsIndex = {star: 0, like: 1, comment: 2};
                let action = this.articles[itemIndex].actions[actionsIndex[type]];

                // 如果已经操作（点赞）过，就不能点赞，直接返回
                if (action.theme === "filled") return;
                axios.put(`/article/${this.articles[itemIndex].id}/actions/`, postData).then(response => {
                    action.theme = 'twoTone';
                    // 如果后端返回201，则表示点过赞，就不增加点赞数
                    if (response.status === 200) action.count++;
                });
            },
            parseActionsData: function (datas) {
                // 处理数据
                for (let data of datas) {
                    // 获取文章内容中的第一张图片，如果有就显示在列表中
                    let pattern = /!\[.*?\]\((.*?)\)/g;
                    if (pattern.test(data.content)) {
                        data.thumbnail = RegExp.$1;
                    }
                    let info = data.expand_infos;
                    data.actions = [
                        {type: "star", icon: 'star', count: info.star || 0, theme: "outlined"},
                        {type: "like", icon: 'like', count: info.like || 0, theme: info.like_by_me ? "twoTone" : "outlined"},
                        {type: "comment", icon: 'message', count: info.comment || 0, theme: "outlined"}
                    ]
                }
                return datas;
            }
        }
    }
</script>

<style scoped>
    >>> .ant-list-item-meta-title > a {
        vertical-align: middle;
    }

    .loadmore-btn {
        width: 20rem;
        border-radius: 24px;
        height: 3em;
        letter-spacing: 2em;
        text-indent: 1em;
    }

    .description {
        word-wrap: break-word;
        word-break: break-all;
    }
</style>